/**
 * 使用 spdlog 做为 log writter
 */

#include <spdlog/spdlog.h>
#include "log.h"

// spdlog 型 writer 数据结构(注意前面几个字段要与 _log_writer_t 的相同)
typedef struct _log_writer_spdlog {
    void (*write)(struct _log_writer_spdlog* self, const char* msg);
    void (*flush)(struct _log_writer_spdlog* self);
    void (*close)(struct _log_writer_spdlog* self);
    spdlog::logger* log;
} log_writer_spdlog_t;

static inline void _spdlog_write(log_writer_spdlog_t* self, const char* msg) {
    // 根据日志字符串中的级别输出
    // "EMERG ", "ALERT ", " CRIT ", "ERROR ", " WARN ", " NOTE ", " INFO ", "DEBUG "
    const char* raw = msg + 30;
    if(strlen(msg) <= 30) self->log->debug(msg);
    else if (memcmp(msg + 24, "DEBUG", 5) == 0) self->log->debug(raw);
    else if (memcmp(msg + 24, " INFO", 5) == 0) self->log->info(raw);
    else if (memcmp(msg + 24, " WARN", 5) == 0) self->log->warn(raw);
    else if (memcmp(msg + 24, "ERROR", 5) == 0) self->log->error(raw);
    else if (memcmp(msg + 24, "ALERT", 5) == 0) self->log->error(raw);
    else if (memcmp(msg + 24, " CRIT", 5) == 0) self->log->critical(raw);
    else if (memcmp(msg + 24, "EMERG", 5) == 0) self->log->critical(raw);
    else if (memcmp(msg + 24, " NOTE", 5) == 0) self->log->info(raw);
	else self->log->debug(msg);
}

extern "C" log_writer_t* logger_add_spdlog(logger_t* logger, void *spdlog) {
    if (!logger || !spdlog) return NULL;
    for (int i = 0; i < LOG_MAX_WRITER; i++) {
        if (logger->writers[i] == NULL) {
            log_writer_spdlog_t *writer = MALLOC0(log_writer_spdlog_t);
            if(!writer) return NULL;
            writer->write = _spdlog_write;
            writer->flush = NULL;
            writer->close = NULL;
            writer->log = spdlog;
            logger->writers[i] = (log_writer_t*)writer;
            return (log_writer_t*)writer;
        }
    }
    return NULL;
}
